home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 2.iso / STUTTGART / LANG / PROLOG / HUMBOLT / HUMBOLTS / _files / _humboltsr / IO._c < prev    next >
Text File  |  1990-12-08  |  28KB  |  1,073 lines

  1. /***************************************************
  2. ****************************************************
  3. **                                                **
  4. **  HU-Prolog     Portable Interpreter System     **
  5. **                                                **
  6. **  Release 1.62   January  1990                  **
  7. **                                                **
  8. **  Authors:      C.Horn, M.Dziadzka, M.Horn      **
  9. **                                                **
  10. **  (C) 1989      Humboldt-University             **
  11. **                Department of Mathematics       **
  12. **                GDR 1086 Berlin, P.O.Box 1297   **
  13. **                                                **
  14. ****************************************************
  15. ***************************************************/
  16.  
  17. #include "systems.h"
  18. #include "types.h"
  19. #include "errors.h"
  20. #include "atoms.h"
  21. #include "files.h"
  22.  
  23. IMPORT void ABORT(),ARGERROR(),ERROR(),SYSTEMERROR();      /* from linebufffer.c */
  24. IMPORT boolean ground();
  25. IMPORT TERM SKELETON();
  26. IMPORT TERM A0,A1;               /* from evalpreds.c     */
  27. IMPORT int INTVALUE();           /* from arith.c         */
  28. IMPORT long lseek();             /* from clib            */
  29. IMPORT boolean LONGRES();        /* from unify.c         */
  30. IMPORT TERM READIN();            /* fom readin.c         */
  31. IMPORT void WRITEOUT(),DISPLAY(); /* from writeout.c      */
  32. IMPORT void ABORT_WRITE();
  33. IMPORT   ENV TOPENV;             /* from prolog.c        */
  34. IMPORT   boolean ECHOFLAG;
  35. IMPORT  void KILLSTACKS();      /* from unify.c */
  36. IMPORT  int ERRORFLAG;
  37. IMPORT  boolean EVENT;
  38. IMPORT  boolean SPYTRACE;
  39. IMPORT string strcpy();                 /* from CLIB            */
  40. IMPORT void destroycl();                /* from database.c      */
  41. IMPORT boolean UserAbort;
  42. IMPORT void CHECKATOM();
  43. IMPORT TERM CALLX;
  44. IMPORT ENV CALLXENV;
  45. IMPORT string s_cls(),s_gotoxy();         /* from sys.c */
  46. IMPORT boolean  xWINDOW_ON;
  47. IMPORT boolean FileExist();
  48. IMPORT boolean isatom();
  49. IMPORT TERM heapterms(),mk2sons();
  50. IMPORT ATOM copyatom();
  51. IMPORT void LONG_JMP(),ERRORJMP();
  52. IMPORT boolean INTRES();
  53. IMPORT int open(),creat(),close(),isatty(),unlink();  /* from clib */
  54. IMPORT int read(),write();
  55. IMPORT void TESTATOM();
  56. IMPORT boolean UNIFY();
  57. #if WINDOWS
  58. IMPORT char t_rc();
  59. #endif
  60.  
  61. /*
  62. EXPORT boolean DOSEE(),DOTELL(),DOSEEK();
  63. EXPORT boolean DOOPEN(),DOCLOSE();
  64. EXPORT boolean DOREAD();
  65. EXPORT boolean DOGET(),DOGET0(),DOASK();
  66. EXPORT void DOPUT(),DOTAB(),DOWRITE(),DOWRITQ();
  67. EXPORT void DONL(),DOSKIP();
  68. EXPORT void DODISLAY();
  69. EXPORT  file inputfile,outputfile
  70. EXPORT  file OpenFile(ATOM,fmode);
  71. EXPORT  void CloseFile(file);
  72. EXPORT  void FileError(ERRORNR);
  73. EXPORT  file_type file_tab[];
  74. EXPORT  boolean FERRORFLAG;
  75. #ifdef ARCHY
  76. EXPORT  boolean SYNCLFLAG;
  77. #endif
  78. EXPORT TERM phy_name();
  79. EXPORT void SYNERROR(),ABORT() , SYSTEMERROR();
  80. EXPORT void GETCHAR(),REGET();
  81. EXPORT boolean LINEENDED(),FILEENDED();
  82. EXPORT char CH,LASTCH;
  83. EXPORT int ERRPOS;
  84. EXPORT   void InitIO()
  85. EXPORT   void ws(string)         write string to outputfile
  86. EXPORT   boolean IOERRORFLAG
  87.  */
  88.  
  89. #if CPM
  90. #define isatty(f)    (!(f<0 || f>2))
  91. #endif
  92.  
  93. FORWARD void FileError();  /* forward declaration */
  94. FORWARD void InitIO();
  95.  
  96. #ifdef DYNMEM
  97. GLOBAL TERM tempterm;  /* for phy_name */
  98. #else
  99. GLOBAL TERM tempterm = nil_term;  /* for phy_name */
  100. #endif
  101.  
  102. /*********************************************************/
  103. /*                filedefinitions                        */
  104. /*********************************************************/
  105.  
  106.  
  107. GLOBAL file_type file_tab[MAXFILES];
  108. GLOBAL boolean FERRORFLAG=true;
  109. #ifdef ARCHY
  110. GLOBAL boolean SYNCLFLAG=true;
  111. #endif
  112. GLOBAL file inputfile,outputfile;
  113.  
  114. GLOBAL TERM phy_name(register ATOM A)
  115. {
  116.     int depth=0;
  117.  
  118.     register TERM F=nil_term;
  119.     register CLAUSE CL;
  120.    start:;
  121.     if(depth++ > 10)ERROR(DEPTHE);
  122.     for(CL=clause(FNAME_2);non_nil_clause(CL);CL=nextcl(CL))
  123.     {
  124.         if(var_sizes(CL) !=0) SYSTEMERROR("phys filename");
  125.         if(name(arg2(head(CL)))==A)
  126.         { F=arg1(head(CL));
  127.           if(isatom(F)){ A=name(F) ; goto start; }
  128.           return F;
  129.         }
  130.     }
  131.     name(tempterm)=A;
  132.     return tempterm;
  133. }
  134.  
  135. GLOBAL file OpenFile(register TERM filename, fmode mode)
  136. {
  137.     register file f;
  138.     deref(filename); 
  139.     if(! ground(filename,MAXDEPTH)) SYSTEMERROR("OpenFiles.0");
  140.     /* search filename in filetab */
  141.     for(f=0;f < MAXFILES;f++)
  142.     { if(FNAME(f)==nil_term || !UNI(filename,FNAME(f))) continue;
  143.       if(!xWINDOW_ON)return f;
  144. #if WINDOWS
  145.       if(FTYPE(f)==NORMFT) return f;
  146.       if(FTYPE(f)==WINDOWFT)
  147.         { if(mode !=look_mode) w_up(FWINPTR(f)); return f; }
  148.       SYSTEMERROR("OpenFiles.1");
  149. #endif
  150.     }
  151.     /* file not open */
  152.     for(f=0;f < MAXFILES ; f++)
  153.         if(FNAME(f)==nil_term) break;
  154.     if(f >=MAXFILES) return ERRFILE;
  155.     if( isatom(filename))
  156.     { string fn;
  157.         fn=tempcopy(name(filename));
  158.         /* an ordinary file */
  159.         switch(mode)
  160.         {
  161.             case look_mode: return NOFILE;
  162.             case read_mode:
  163.                      if((FINPTR(f)=open(fn,0))<0)
  164.                          return NOFILE;
  165.                      CANREAD(f)=!(CANWRITE(f)=false);
  166.                      break;
  167.             case write_mode:
  168.                      if((FOUTPTR(f)=creat(fn,0666))<0)
  169.                          return NOFILE;
  170.                      CANREAD(f)=!(CANWRITE(f)=true);
  171.                      break;
  172.             case read_write:
  173.                      if((FOUTPTR(f)=FINPTR(f)=open(fn,2))<0)
  174.                      {
  175.                          if(FileExist(fn)) return NOFILE;
  176.                          (void)close(creat(fn,0666));
  177.                          if((FINPTR(f)=FOUTPTR(f)=open(fn,2))<0)
  178.                          {
  179.                              unlink(fn);
  180.                              return NOFILE;
  181.                          }
  182.                      }
  183.                      CANREAD(f)=CANWRITE(f)=true;
  184.                      break;
  185.              default:
  186.                      SYSTEMERROR("OpenFile.2");
  187.         } /* switch */
  188.         FNAME(f)=SKELETON(NOT_1,filename); /* see SKELETON ! */
  189.         FTYPE(f)=NORMFT;
  190.         ISEOF(f)=ISINPUT(f)=false;
  191.         ISTTY(f)=isatty(f);
  192.         FLINENO(f)=0;
  193.         FCHARPOS(f)=FBUFLENGTH(f)=0;
  194.         return f;
  195.     }
  196. #if WINDOWS
  197.     else if(xWINDOW_ON && name(filename)==WINDOW_6)
  198.     {
  199.         int a,b,c,d;
  200.         static string winname;
  201.         byte
  202.         attr=0;
  203.         TERM T,TT;
  204.         if(mode==look_mode) return NOFILE;
  205.         TT=son(filename); a=INTVALUE(TT);
  206.         next_br(TT); b=INTVALUE(TT);
  207.         next_br(TT); c=INTVALUE(TT);
  208.         next_br(TT); d=INTVALUE(TT);
  209.         next_br(TT);T=TT;deref(T);
  210.         CHECKATOM(T);
  211.         winname=tempcopy(copyatom(name(T)));
  212.  
  213.         next_br(TT);
  214.         deref(TT);
  215.         while(name(TT)==CONS_2)
  216.           { T=arg1(TT);TT=arg2(TT);
  217.             switch(name(T))
  218.             { case BLINK_0:   attr |=BLINK;break;
  219.               case REVERSE_0: attr |=REVERSE;break;
  220.               case BOLD_0:    attr |=BOLD;break;
  221.               case UNDER_0:   attr |=UNDERLINE;break;
  222.             }
  223.           }
  224.         TESTATOM(NIL_0,TT);
  225.         FTYPE(f)=WINDOWFT;
  226.         if((FWINPTR(f)=w_create(a,b,c,d,winname,attr))==NOWINDOW) 
  227.             return ERRFILE;
  228.         FNAME(f)=SKELETON(NOT_1,filename);
  229.         ISEOF(f)=ISINPUT(f)=false;
  230.         ISTTY(f)=true;
  231.         CANREAD(f)=CANWRITE(f)=true;
  232.         return f;
  233.     }
  234. #endif
  235.     else return NOFILE;
  236. }
  237.  
  238.  
  239.  
  240. GLOBAL void CloseFile(register int f)
  241. {
  242.     if(f<4 || FNAME(f)==nil_term) return;
  243.     if(FTYPE(f)==NORMFT)
  244.     {
  245.         if(FINPTR(f) > 2) (void)close(FINPTR(f));
  246.         if(FOUTPTR(f) > 2) (void)close(FOUTPTR(f));
  247.     }
  248. #if WINDOWS
  249.     else if(xWINDOW_ON && FTYPE(f)==WINDOWFT) w_remove(FWINPTR(f));
  250. #endif
  251.     else SYSTEMERROR("CloseFile.1");
  252.     FNAME(f)=nil_term;
  253. }
  254.  
  255. /******************************************************/
  256. /*                     basicio                        */
  257. /******************************************************/
  258.  
  259. #define MAXDIGITS 25   /* max digits for number conversation */
  260. LOCAL  char numbuffer[MAXDIGITS]; /* for number conversation */
  261.  
  262.  
  263. GLOBAL int IOERRORFLAG=0;
  264.  
  265. /* short hand notation for basic i/o in this module */
  266. #define NOTREAD  0
  267. #define NOTWRITE         1
  268. #define Errornumber      int
  269.  
  270.  
  271. LOCAL char *errmsg[]={
  272.                        "read error",/* NOTREAD */
  273.                        "write error" /* NOTWRITE */
  274.                       };
  275.  
  276. LOCAL void IO_Error(TERM f, Errornumber e)
  277. { if(IOERRORFLAG++>3) ABORT(IOERROR);
  278.   if((outputfile=OpenFile(phy_name(STDERR_0),write_mode))<0)
  279.       ABORT(IOERROR);
  280.   ws("\ni/o error in file '"); DISPLAY(f); ws("' : "); ws(errmsg[e]);
  281.   ERROR(IOERROR);
  282. }
  283.  
  284. #if REALARITH
  285.  
  286. GLOBAL char* ftoa(double d)
  287. {
  288.    register char *cp; 
  289.    register r;
  290.    register int expo ;
  291.  
  292.    cp=numbuffer;
  293.    if(d !=0.0 && d==10.0*d)
  294.    {/*overflow */ 
  295.         strcpy(numbuffer,"99e999");
  296.         return (char *)numbuffer;
  297.    }
  298.    if( d < 0.0){
  299.  *cp++= '-'; d= -d; 
  300.  }
  301.    *cp++= '0' ;
  302.    *cp++= '.';
  303.    r=0;
  304.    expo=0;
  305.    if( d==0.0  ) {
  306.  *cp++= '0';
  307.  *cp++=0; 
  308.  return (char *)numbuffer;
  309.  }
  310.    if(d >=1.0 ){
  311.  while(d >=1.0e+9){
  312.          r +=10;d *=1.0e-10;
  313.          }
  314.  while(d >=1.0 ){
  315.          r++ ; d *=1.0e-1;
  316.          }
  317.  }
  318.    else {
  319.  while(d < 1.0e-10){
  320.          r -=10; d *=1.0e+10;
  321.          }
  322.  while(d < 1.0e-1){
  323.          r-- ; d *=10.0 ; 
  324.          }
  325.  }
  326.    expo=r ;
  327. #if MAXDIGITS-9<12
  328.    r=MAXDIGITS-9;
  329. #endif
  330. #if MAXDIGITS-9>=12
  331.    r=12;
  332. #endif
  333.    while(r-- >0){
  334.          register i;
  335.          d *=1.0e+1; i= (int)d ; d -= (double)i;
  336.          *cp++= '0' + i;
  337.     }
  338.    if(*(cp-1)=='9')
  339.    {
  340.         while(*--cp=='9');
  341.         if(*cp== '.') 
  342.           { *((cp++)-1)= '1';*cp++= '0';}
  343.         else
  344.           { (*cp++)++;*cp++= '0';}
  345.    }
  346.    while(*--cp=='0');
  347.    if(*cp++== '.') *cp++= '0';
  348.    *cp++= 'e';
  349.    if(expo <0)  { *cp++= '-' ; expo= -expo;}
  350.    else *cp++= '+';
  351.    if( expo >=100 ){*cp++='0' + expo / 100 ; expo %=100 ;} 
  352.    *cp++= '0' + expo/10;
  353.    *cp++='0' + expo %10;
  354.    *cp=0;
  355.    return (char *)numbuffer;
  356. }
  357.  
  358. #endif
  359.  
  360. #if LONGARITH 
  361. GLOBAL char *ltoa(long v)
  362. {
  363.       long int r; 
  364.       register char *p; 
  365.       int sign;
  366.       if(v<0l) {sign=1; r= -v;} else {sign=0; r=v;}
  367.       p= &numbuffer[MAXDIGITS-2];
  368.       if(r==0l) *p--='0';
  369.       else do *p--=r%10l+'0'; while(r/=10l);
  370.       if(sign) *p--='-';
  371.       p++;
  372.       numbuffer[MAXDIGITS-1]=0;
  373.       return p;
  374. }
  375. #endif
  376.  
  377. GLOBAL char *itoa(int v)
  378. { int r; 
  379.   register char *p; 
  380.   int sign, h=0;
  381.       if(v==minint) {v++; h=1; }
  382.       if(v<0l) {sign=1; r= -v;} else {sign=0; r=v;}
  383.       p= &numbuffer[MAXDIGITS-2];
  384.       if(r==0l) *p--='0';
  385.       else do *p--=r%10+'0';
  386.     while(r/=10);
  387.       numbuffer[MAXDIGITS-2]+=h;
  388.       if(sign) *p--='-';
  389.       /* h= &numbuffer[MAXDIGITS-2]-p; */
  390.       p++;
  391.       numbuffer[MAXDIGITS-1]=0;
  392.       return p;
  393. }
  394.  
  395. GLOBAL void wi(int N)
  396. { ws(itoa(N)); }
  397.  
  398. GLOBAL void wc( char ch)
  399. { static char c[2];c[0]=ch;c[1]='\0';ws(c); }
  400.  
  401. GLOBAL void out_1(register char *s)
  402. {
  403.     (void)write(1,s,strlen(s));
  404. }
  405.  
  406. GLOBAL void out_2(register char *s)
  407. {
  408.     (void)write(2,s,strlen(s));
  409. }
  410.  
  411. #if !CPM
  412.  
  413. #define OBLEN 85
  414.  
  415. LOCAL char outbuffer[OBLEN];
  416. LOCAL int outbufpos=0;
  417. LOCAL boolean o_buf_flag=false;
  418.  
  419. LOCAL mws(string s)
  420. { register int i; register char *p;
  421.   for(i=0, p=s; *p; p++) i++;
  422.   if(FTYPE(outputfile)==NORMFT)
  423.   {
  424.       if(write(FOUTPTR(outputfile),s,i) !=i && !UserAbort)
  425.           IO_Error(FNAME(outputfile),NOTWRITE);
  426.   }
  427. #if WINDOWS
  428.   else if(xWINDOW_ON && FTYPE(outputfile)==WINDOWFT)
  429.       w_puts(FWINPTR(outputfile),s);
  430. #endif
  431.   else SYSTEMERROR("ws.1");
  432. }
  433.  
  434. GLOBAL void out_buffer(int mode)
  435. {
  436.     switch(mode)
  437.     {
  438.         case BUF_ON: o_buf_flag=true;break;
  439.         case BUF_OFF: o_buf_flag=false;
  440.         case BUF_FLUSH: outbuffer[outbufpos]= '\0';
  441.                         mws(outbuffer);
  442.                         outbufpos=0;
  443.                         break;
  444.     }
  445. }
  446.   
  447. GLOBAL void ws(register char *s)
  448. /* write string */
  449. {
  450.     if(o_buf_flag)
  451.     {
  452.         while(*s)
  453.         {
  454.             outbuffer[outbufpos++]= *s++;
  455.             if(outbufpos > OBLEN-3)
  456.             {
  457.                 outbuffer[outbufpos]= '\0';
  458.                 mws(outbuffer);
  459.                 outbufpos=0;
  460.             }
  461.         }
  462.     }
  463.     else 
  464.     mws(s);
  465. }
  466. #endif
  467.  
  468. #if CPM
  469. GLOBAL void ws(register char *s)
  470. /* write string */
  471. { register int i; register char *p;
  472.   for(i=0, p=s; *p; p++) i++;
  473.   if(write(FOUTPTR(outputfile),s,i) !=i && !UserAbort)
  474.           IO_Error(FNAME(outputfile),NOTWRITE);
  475. }
  476. #endif
  477.  
  478. /****************** I N I T I A L I S A T I O N *****************/
  479.  
  480. LOCAL initcounter=0;
  481.  
  482. LOCAL TERM node(register ATOM A)
  483. { register TERM T;
  484.   T=heapterms(1);
  485.   name(T)=A; son(T)=nil_term; return T;
  486. }
  487.  
  488. GLOBAL void InitIO(void)
  489.   int i;
  490.   tempterm = nil_term;
  491.   if(initcounter++) { ISEOF(inputfile)=false; return; } 
  492.      FNAME(0)=node(STDIN_0); ISEOF(0)=false; ISTTY(0)=isatty(0);
  493.      CANREAD(0)=!(CANWRITE(0)=false); ISINPUT(0)=true;
  494.      FCHARPOS(0)=FBUFLENGTH(0)=0;FLINENO(0)=1;
  495.      FLOGNAME(0)=STDIN_0;
  496.  
  497.      FNAME(1)=node(STDOUT_0); ISEOF(1)=false; ISTTY(1)=isatty(1);
  498.      CANREAD(1)=!(CANWRITE(1)=true); ISINPUT(1)=false;
  499.      FLOGNAME(1)=STDOUT_0;
  500.  
  501.      FNAME(2)=node(STDERR_0); ISEOF(2)=false; ISTTY(2)=isatty(2);
  502.      CANREAD(2)=!(CANWRITE(2)=true); ISINPUT(2)=false;
  503.      FLOGNAME(2)=STDERR_0;
  504.  
  505.      FNAME(3)=node(STDTRACE_0); ISEOF(3)=false; ISTTY(3)=isatty(0);
  506.      CANREAD(3)=!(CANWRITE(3)=true); ISINPUT(3)=false;
  507.      FLOGNAME(3)=STDTRACE_0;
  508.  
  509. #if HELP
  510.      FNAME(4)=node(STDHELP_0); ISEOF(4)=false; ISTTY(4)=isatty(0);
  511.      CANREAD(4)=!(CANWRITE(4)=true); ISINPUT(4)=false;
  512.      FLOGNAME(4)=HELP_0;
  513. #endif
  514. #if !HELP
  515.      FNAME(4)=nil_term;
  516. #endif
  517. #if HELP 
  518.      for(i=0;i<5;i++)
  519. #endif
  520. #if !HELP
  521.      for(i=0;i<4;i++)
  522. #endif
  523.      {
  524.          FTYPE(i)=NORMFT;
  525.          FOUTPTR(i)=FINPTR(i)=i;
  526. #if WINDOWS
  527.          if(xWINDOW_ON)
  528.          {
  529.              FTYPE(i)=WINDOWFT;
  530.              FWINPTR(i)=STDWIN;
  531.              CANREAD(i)=CANWRITE(i)=true;
  532.          }
  533. #endif
  534.      }
  535.      FINPTR(4)=FINPTR(3)=0;
  536.      FOUTPTR(4)=FOUTPTR(3)=1;
  537.      inputfile=STDIN;outputfile=STDOUT;
  538.      for(i=5;i<MAXFILES;i++) FNAME(i)=nil_term;
  539.     tempterm=heapterms(1); son(tempterm)=nil_term;
  540.     /* md: used in phy_name */
  541. }
  542.  
  543. GLOBAL char CH, LASTCH;
  544. GLOBAL int  ERRPOS;
  545.  
  546. /* also used in read.c */
  547. GLOBAL boolean unget=false;
  548. GLOBAL int FirstCharPos=0;
  549.  
  550. GLOBAL void fillbuffer(void)
  551. {
  552.  FirstCharPos=CHARPOS=ERRPOS=LINELENGTH=0;
  553. #if WINDOWS
  554.   if(FTYPE(inputfile)==NORMFT)
  555. #endif
  556.   {
  557.     if((LINELENGTH=read(FINPTR(inputfile),LINEBUF,BUFLENGTH-1)) < 0)
  558.         IO_Error((FNAME(inputfile)),NOTREAD);
  559.     if(LINELENGTH==0) ISEOF(inputfile)=true; else ISEOF(inputfile)=false;
  560.   }
  561. #if WINDOWS
  562.   else if(xWINDOW_ON) /* FTYPE(inputfile)==WINDOWFT */
  563.   {
  564.     if((LINELENGTH=w_gets(FWINPTR(inputfile),LINEBUF,BUFLENGTH-1)) < 0)
  565.         IO_Error((FNAME(inputfile)),NOTREAD);
  566.     if(LINELENGTH==0) ISEOF(inputfile)=true; else ISEOF(inputfile)=false;
  567.   }
  568. #endif
  569.  LINEBUF[LINELENGTH]=0;
  570. }
  571.  
  572. GLOBAL boolean FILEENDED(void)
  573. {
  574. if(!unget && CHARPOS >=LINELENGTH && !ISTTY(inputfile))
  575.  fillbuffer();
  576. return (!unget && ISEOF(inputfile) && (CHARPOS >=LINELENGTH));
  577. }
  578.  
  579. /* Get the next character of the current input file in 'ch'. */
  580. /* inline-code in READIN */
  581. GLOBAL void GETCHAR(void)
  582.   if(unget){unget=false; return;}
  583.   LASTCH=CH;
  584.   if(FILEENDED()){CH= '\n'; return; }
  585.   if( CHARPOS >=LINELENGTH ){
  586.      /* no char's in the buffer */
  587.      fillbuffer();
  588.      }
  589.   CH=LINEBUF[CHARPOS++] ;if(ECHOFLAG)wc(CH);
  590.   if(CH== '\n') {FirstCharPos=CHARPOS ; ERRPOS=0; LINENUMBER++;}
  591. }
  592.  
  593. GLOBAL boolean LINEENDED(void)
  594. { if(CHARPOS >=LINELENGTH && !ISTTY(inputfile))
  595.  fillbuffer();
  596.   return (FILEENDED() || LINEBUF[CHARPOS]== '\n');
  597. }
  598.  
  599. GLOBAL void REGET(void)
  600. { unget=true;
  601. }
  602.  
  603. LOCAL struct { int ERRNR; string ERRMSG; } ERRTAB[]=
  604. { { ABORTE         ,  "execution aborted"  },
  605.   { ARGE           ,  "unsuitable argument(s) to system predicates"  },
  606.   { ATOMSPACEE     ,  "out of atom space"  },
  607.   { BADARITYE      ,  "arity of functor out of range"  },
  608.   { BADCDDE        ,  "probably malformed ',..'"  },
  609.   { BADCHARE       ,  "character value out of range"  },
  610.   { BADDOTE        ,  "closing bracket missing"  },
  611.   { BADEXPE        ,  "malformed expression"  },
  612.   { BADKETE        ,  "unmatched closing bracket"  },
  613.   { BADTYPE        ,  "bad numerical argument type "  },
  614.   { CALLE          ,  "unsuitable arguments to 'call'"  },
  615.   { COMMENTE       ,  "unterminated comment"  },
  616.   { DEPTHE         ,  "nesting too deep  probably cyclic term"  },
  617.   { DIV0E          ,  "division or mod by zero"  },
  618.   { EOFE           ,  "unexpected end of file"  },
  619.   { FRAMESPACEE    ,  "out of frame space"  },
  620.   { IOERROR        ,  "I/O error"  },
  621.   { LOCALSPACEE    ,  "out of local stack space"  },
  622.   { NEEDOPE        ,  "infix or postfix operator expected"  },
  623.   { NEEDQUOTEE     ,  "closing quote expected"  },
  624.   { NEEDRANDE      ,  "operand or prefix operator expected"  },
  625.   { NUMBERSYNE     ,  "bad number syntax"  },
  626.   { NVARSE         ,  "out of variable table space"  },
  627.   { PRECE          ,  "operator has unsuitable precedence"  },
  628.   { PROGFAILE      ,  "goal failed during program input"  },
  629.   { READNESTE      ,  "nesting too deep in input"  },
  630.   { READSTACKE     ,  "read stack overflow"  },
  631.   { STDFUNCARGE    ,  "standard function called with wrong argument"  },
  632.   { SYSPROCE       ,  "accessing or modifying system procedures"  },
  633.   { TRAILSPACEE    ,  "out of trail space"  },
  634.   { UNDEFFUNCE     ,  "undefined function in expression"  },
  635.   { VARSPACEE      ,  "out of variable name space"  },
  636.   { WIERDCHE       ,  "illegal character in input"  },
  637.   { aSTRINGSPACEE  ,  "out of string space"  },
  638.   { FPEXCEPTE      ,  "floating point exception" },
  639.   { CANTCR         ,  "can't create file" },   
  640.   { CANTOP         ,  "can't open file" },      
  641.   { NOTOPEN        ,  "file is not open" },      
  642.   { ISTTYE         ,  "file is a tty" },          
  643.   { TOMANY         ,  "to many files" },           
  644.   { CUROUT         ,  "file is current outputfile" },
  645.   { CURINP       ,  "file is current inputfile" },
  646.   { ONLOUT         ,  "file is only open for output" },
  647.   { ONLINP         ,  "file is only open for input" }, 
  648.   { CODESPACEE     ,  "out of code space" },
  649.   { LABELSPACEE    ,  "out of label space" },
  650.   { UNDEFLABEL     ,  "undefined label" },
  651.   { 0              ,  "" }
  652. };
  653.  
  654. GLOBAL string ERRORMSG(int N)
  655. { register int I;
  656.     for(I=0; ERRTAB[I].ERRNR; I++)
  657.       if(ERRTAB[I].ERRNR==N) break;
  658.   return ERRTAB[I].ERRMSG;
  659. }
  660.  
  661. GLOBAL void ABORT(int N)
  662.   static abort_counter=0;
  663.   if(N !=NOERROR)
  664.   { 
  665.     if(abort_counter++  >  2 ||
  666.        (outputfile=OpenFile(phy_name(STDERR_0),write_mode)) < 0)
  667.       outputfile=STDERR;
  668.     ws("\n");
  669.     if(non_nil_term(CALLX)) ABORT_WRITE(CALLX);
  670.     ws("\nERROR ");wi(N);
  671.     ws(": "); ws(ERRORMSG(N)); ws(".\n"); 
  672. #if WINDOWS
  673.     if(xWINDOW_ON && FTYPE(outputfile)==WINDOWFT)
  674.     {
  675.           ws("\npress any key to continue");
  676.           t_rc(); /* lese ein zeichen vom terminal ohne echo */
  677.           CloseFile(outputfile);
  678.     }
  679. #endif
  680.   }
  681.   ERRORFLAG=0; EVENT=SPYTRACE;
  682.   if(TOPENV) KILLSTACKS(TOPENV);
  683.   abort_counter=0;
  684.   LONG_JMP(101);
  685. }
  686.  
  687.  
  688. GLOBAL void ARGERROR(void)
  689. { ERROR(ARGE); }
  690.  
  691. GLOBAL void ERROR(int N)
  692. {
  693.     ERRORFLAG=N;
  694.     EVENT=true;
  695.     ERRORJMP();
  696. }
  697.  
  698. GLOBAL void FileError(int error)
  699. {
  700.     if(!FERRORFLAG) return;
  701.     ERROR(error);
  702. }
  703.  
  704. /* Output an error message and recover if possible */
  705.  
  706. GLOBAL void SYNERROR(int N)
  707. { int  I;
  708.   if(FLOGNAME(inputfile) !=STDIN_0)
  709.   {  if((outputfile=OpenFile(phy_name(STDERR_0),write_mode)) < 0)
  710.         outputfile=STDERR;
  711.      ws("\nSYNTAXERROR  file: ");
  712.      WRITEOUT(phy_name(FLOGNAME(inputfile)),false);
  713.      ws("  line: ");
  714.      wi(LINENUMBER+1);
  715.      ws("  position: ");
  716.      wi(CHARPOS-FirstCharPos);
  717.      ws("\n");
  718.      if(!ECHOFLAG) { 
  719.         for(I=FirstCharPos;LINEBUF[I]!='\n' && I < LINELENGTH; I++)
  720.             wc(LINEBUF[I]);
  721.         ws("\n");
  722.         }
  723. #ifdef ARCHY
  724.      if( SYNCLFLAG ) CloseFile( inputfile );
  725. #endif
  726.  
  727.   }
  728.   for(I=FirstCharPos; I<ERRPOS-1; ++I)
  729.     if(LINEBUF[I]=='\t') ws("\t"); else ws(" ");
  730.   ws("^"); 
  731.  
  732.   if(inputfile==STDIN || FTYPE(inputfile)==WINDOWFT) 
  733.       CHARPOS=LINELENGTH;
  734.   CALLX=nil_term;
  735.   ERROR(N);
  736. }
  737.  
  738. GLOBAL void SYSTEMERROR(string m)
  739. { out_2("\n\n[System Error in: "); out_2(m); out_2("]\n"); 
  740.   LONG_JMP(999);
  741.  
  742.  
  743.  
  744. #define abs(l)           (((l) < 0L) ? -(l) : (l))
  745.  
  746. LOCAL file f;
  747. LOCAL TERM filename;
  748. LOCAL ATOM matom;
  749. LOCAL TERM seestack[MAXFILES];
  750. LOCAL int seesptr = 0;
  751.  
  752. GLOBAL boolean DOSEE(void)
  753. {
  754.     CHECKATOM(A0);
  755.     matom=name(A0);
  756.     if(matom==USER_0)matom=STDIN_0;
  757.     filename=phy_name(matom);
  758.     f=OpenFile(filename,read_mode);
  759.     switch(f)
  760.     {
  761.          case NOFILE:  FileError(CANTOP); return false;
  762.          case ERRFILE: FileError(TOMANY); return false;
  763.          default:      
  764.                if(f==outputfile && FTYPE(f)==NORMFT)
  765.                    { FileError(CUROUT); return false; } 
  766.                if(!CANREAD(f))
  767.                    { FileError(ONLOUT); return false; }
  768.                if( inputfile != f ) {
  769.                   seestack[seesptr] = FNAME(inputfile);
  770.                   if( ++seesptr > MAXFILES )
  771.                     SYSTEMERROR( "SEE.1: Too many nested see's" );
  772.                   inputfile=f;
  773.                 }
  774.               if(!ISINPUT(inputfile))
  775.                {
  776.                  ISINPUT(inputfile)=true;
  777.                  CHARPOS=LINELENGTH=0;
  778.                }
  779.     }
  780.     FLOGNAME(inputfile)=copyatom(matom);
  781.     return true;
  782. }
  783.  
  784. GLOBAL boolean DOSEEN(void)
  785. {
  786.      if( seesptr <= 0 ) {
  787.         seesptr = 0;     
  788.         return true;
  789.      }
  790.      CloseFile( inputfile );
  791.      inputfile = OpenFile( seestack[--seesptr], read_mode );
  792.      ISEOF(inputfile) = false;
  793.      return true;
  794. }
  795.  
  796. GLOBAL boolean DOOPEN(void)
  797. {
  798.     CHECKATOM(A0);
  799.     matom=name(A0);
  800.     if(matom==USER_0) return true; /* user is open ! */
  801.     filename=phy_name(matom);
  802.     switch(f=OpenFile(filename,read_write))
  803.     {
  804.          case NOFILE:  FileError(CANTOP);return false;
  805.          case ERRFILE: FileError(TOMANY);return false;
  806.     }
  807.     FLOGNAME(f)=copyatom(matom);
  808.     return true;
  809. }
  810.  
  811. GLOBAL boolean DOCLOSE(void)
  812. {
  813.     CHECKATOM(A0);
  814.     matom=name(A0);
  815.     if(matom==USER_0) return true; /* ! */
  816.     filename=phy_name(matom);
  817.     if((f=OpenFile(filename,look_mode))==NOFILE)
  818.     {
  819.          FileError(NOTOPEN);return false;
  820.     }
  821.     CloseFile(f);
  822.     if(inputfile==f) 
  823.         if((inputfile=OpenFile(phy_name(STDIN_0),read_mode)) < 0)
  824.         inputfile=STDIN;
  825.     if(outputfile==f)
  826.         if((outputfile=OpenFile(phy_name(STDOUT_0),write_mode)) < 0)
  827.         outputfile=STDOUT;
  828.     return true;
  829. }
  830.  
  831.  
  832. GLOBAL boolean DOTELL(void)
  833. {
  834.     CHECKATOM(A0);
  835.     matom=name(A0);
  836.     if(matom==USER_0)matom=STDOUT_0;
  837.     filename=phy_name(matom);
  838.     switch(f=OpenFile(filename,write_mode))
  839.     {
  840.          case NOFILE:  FileError(CANTCR); return false;
  841.          case ERRFILE: FileError(TOMANY); return false;
  842.          default:      
  843.                if(f==inputfile && FTYPE(f)==NORMFT)
  844.                    { FileError(CURINP); return false; }
  845.                if(!CANWRITE(f))
  846.                    { FileError(ONLINP); return false; }
  847.                outputfile=f;
  848.               if(ISINPUT(outputfile) && FTYPE(f)==NORMFT)
  849.               {
  850.                  ISINPUT(outputfile)=false;
  851.                  (void)lseek(outputfile,
  852.                        (long)(FCHARPOS(outputfile)-
  853.                              FBUFLENGTH(outputfile)),1);
  854.              }
  855.     }
  856.     FLOGNAME(outputfile)=copyatom(matom);
  857.     return true;
  858. }
  859.  
  860.  
  861. #if !CPM
  862. GLOBAL boolean DOSEEK(void)
  863. {
  864.     long l;
  865.     boolean res;
  866.  
  867.     CHECKATOM(A0);
  868.     if(name(A0)==USER_0) ARGERROR();
  869.     matom=name(A0);
  870.     filename=phy_name(matom);
  871.     if((f=OpenFile(filename,look_mode))<0)
  872.         { FileError(NOTOPEN); return false; }
  873.     if((f<3)||ISTTY(f)||FTYPE(f) !=NORMFT)
  874.         { FileError(ISTTYE); return false; }
  875.     switch(name(A1))
  876.     {
  877.          case END_0:
  878.                  l=lseek(f,0L,2);
  879.                  res= (l >=0L);
  880.                  FBUFLENGTH(f)=FCHARPOS(f)=0;
  881.                  break;
  882.          case INTT: l=(long)ival(A1); goto contseek;
  883. #if LONGARITH
  884.          case LONGT: l=  longval(A1);
  885. #endif
  886.       contseek:  res= (lseek(f,abs(l),(l >=0) ? 0 : 2) >=0L);
  887.                  FBUFLENGTH(f)=FCHARPOS(f)=0;
  888.                  break;
  889.          case UNBOUNDT:
  890.                  l=lseek(f,(long)0,1);
  891.                  l=l-(long)
  892.                      (ISINPUT(f) ? (FBUFLENGTH(f)-FCHARPOS(f)):0);
  893. #if LONGARITH
  894.                  return LONGRES(A1,l);
  895. #endif
  896. #if ! LONGARITH
  897.                  return INTRES(A1,(int)l);
  898. #endif
  899.          default: ARGERROR();
  900.     }
  901.     return res;
  902. }
  903. #endif
  904.  
  905. LOCAL TERM oldfilename;
  906. GLOBAL void setinfile(void)
  907. {
  908.     oldfilename=FNAME(inputfile);
  909.     if((inputfile=OpenFile(phy_name(STDIN_0),read_mode)) < 0)
  910.     {
  911.         inputfile=STDIN ; /*  ?????? */
  912.     }
  913. }
  914.  
  915. GLOBAL void getinfile(void)
  916. {
  917.     if((inputfile=OpenFile(oldfilename,read_mode)) < 0)
  918.         SYSTEMERROR("getinfile.1");
  919. }
  920.  
  921. GLOBAL void setoutfile(void)
  922. {
  923.     oldfilename=FNAME(outputfile);
  924.     if((outputfile=OpenFile(phy_name(STDOUT_0),write_mode)) < 0)
  925.     {
  926.         outputfile=STDOUT ; /*  ?????? */
  927.     }
  928. }
  929. GLOBAL void getoutfile(void)
  930. {
  931.     if((outputfile=OpenFile(oldfilename,write_mode)) < 0)
  932.         SYSTEMERROR("getoutfile.1");
  933. }
  934.  
  935. GLOBAL boolean DOGET0(void)
  936.     register int ch;
  937.     if(FILEENDED())ch= -1;
  938.     else { GETCHAR(); ch=CH; }
  939.     return INTRES(A0,ch);
  940. }
  941.  
  942. GLOBAL boolean DOGET(void)
  943.     register int ch;
  944.   nextch:
  945.     if(FILEENDED()) ch= -1; 
  946.     else 
  947.     { GETCHAR();
  948.       if(CH<=' ' || CH>=127) goto nextch;
  949.       ch= (int)CH;
  950.     }
  951.     return INTRES(A0,ch);
  952. }
  953.  
  954. GLOBAL void DOSKIP(void)
  955. {
  956.     register int n;
  957.     n=(INTVALUE(A0) & 255);
  958.   nextch:
  959.     if(FILEENDED()) return;
  960.     GETCHAR();
  961.     if(CH!=n) goto nextch;
  962. }
  963.  
  964. GLOBAL boolean DOASK(void)
  965. {
  966.     register int ch;
  967.   nextch:
  968.     if(FILEENDED()) return true;
  969.     GETCHAR(); 
  970.     if(CH==0) goto nextch;
  971.     ch=CH;
  972.     while((CH!=10) && !FILEENDED())
  973.         GETCHAR();
  974.     if(name(A0)==UNBOUNDT) return INTRES(A0,ch);
  975.     return INTVALUE(A0)==ch;
  976. }
  977.  
  978. GLOBAL void DOTAB(void)
  979. {  register int n;
  980.    n=INTVALUE(A0);
  981. #if !CPM
  982.    out_buffer(BUF_ON);
  983. #endif
  984.    while(n-->0) ws(" ");
  985. #if !CPM
  986.    out_buffer(BUF_OFF);
  987. #endif
  988. }
  989.  
  990. GLOBAL void DOPUT(void)
  991. {
  992. #if !CPM
  993.   out_buffer(BUF_ON);
  994. #endif
  995.     while(name(A0)==CONS_2)
  996.       { wc((char)(INTVALUE(arg1(A0)) & 255)); A0=arg2(A0); }
  997.     if(name(A0)!=NIL_0)
  998.          wc((char)((INTVALUE(A0))&255));
  999. #if !CPM
  1000.   out_buffer(BUF_OFF);
  1001. #endif
  1002. }
  1003.  
  1004.  
  1005. GLOBAL boolean DOFASSIGN(void)
  1006. {
  1007.     register CLAUSE CL,CC;
  1008.     TERM F;
  1009.  
  1010.     if(! ground(A0,MAXDEPTH)) ARGERROR();
  1011.     if(!ground(A1,MAXDEPTH)) 
  1012.     {
  1013.         for(CL=clause(FNAME_2);non_nil_clause(CL);CL=nextcl(CL))
  1014.         {
  1015.             if(var_sizes(CL) !=0) SYSTEMERROR("assign");
  1016.             if(UNI(A0,arg2(head(CL)))) 
  1017.                return UNI(A1,arg1(head(CL)));
  1018.         }
  1019.         return false;
  1020.     }
  1021.  
  1022.     for(CL=CC=clause(FNAME_2);non_nil_clause(CL);CC=CL,CL=nextcl(CL))
  1023.     {
  1024.         if(var_sizes(CL) !=0) SYSTEMERROR("assign");
  1025.         if(UNI(A0,arg2(head(CL))))
  1026.         { if(CL==clause(FNAME_2)) clause(FNAME_2)=nextcl(CL);
  1027.           else nextcl(CC)=nextcl(CL);
  1028.           destroycl(CL);
  1029.           break;
  1030.         }
  1031.     }
  1032.  
  1033.     if(UNI(A0,A1)) return true;
  1034.     F=mk2sons(UNBOUNDT,nil_term,UNBOUNDT,nil_term);
  1035.     (void)UNI(F,A1);(void)UNI(br(F),A0);
  1036.     CL=heapterms(3);
  1037.     name(head(CL))=FNAME_2; son(head(CL))=SKELETON(FNAME_2,F);
  1038.     name(body(CL))=nil_atom; nextcl(CL)=clause(FNAME_2); setnvars(CL,0); 
  1039.     clause(FNAME_2)=CL;
  1040.     return true;
  1041. }
  1042.  
  1043. GLOBAL void DOCLS(void)
  1044. #if WINDOWS
  1045.   if(xWINDOW_ON && FTYPE(outputfile)==WINDOWFT) 
  1046.     w_cls(FWINPTR(outputfile));
  1047.   else 
  1048. #endif
  1049.     ws(s_cls());
  1050. }
  1051.  
  1052. GLOBAL void DOGOTOXY(void)
  1053. { register int S,Z;
  1054.   extern TERM A0,A1;
  1055.   extern int INTVALUE();
  1056.   S=INTVALUE(A0);Z=INTVALUE(A1);
  1057. #if WINDOWS
  1058.   if(xWINDOW_ON && FTYPE(outputfile)==WINDOWFT) 
  1059.     w_gotoxy(FWINPTR(outputfile),S,Z);
  1060.   else 
  1061. #endif
  1062.     ws(s_gotoxy(S,Z));
  1063. }
  1064.     
  1065.  
  1066.